package demo.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;

import com.google.common.util.concurrent.RateLimiter;

import net.sf.cglib.beans.BeanCopier;
public class BeanUtil {

	public static void main(String[] args) {
	    RateLimiter limiter = RateLimiter.create(2.0) ;
		Map<String,String> map = new HashMap<String,String>();
		map.put("a", "aa");
		map.put("b", "bb");
		map.put("c", "cc");
		A bean = new A();
//		BeanUtils.copyProperties(map, bean);
		try {
//			BeanUtils.copyProperties(bean, map);
			BeanUtils.populate(bean, map);
		} catch (IllegalAccessException | InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		/*try {
			BeanUtils.describe(bean);
		} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		System.out.println(bean.getA()+bean.getB()+bean.getC());
		
	}

    /**
     * 深拷贝
     * 
     * @param src
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(src);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
        List<T> dest = (List<T>) inputStream.readObject();

        if (outputStream != null) {
            outputStream.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        return dest;
    }

    /**
     * 深拷贝
     * 
     * @param src
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static <T> T deepCopy(T src) throws IOException, ClassNotFoundException {

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(src);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
        T dest = (T) inputStream.readObject();

        if (outputStream != null) {
            outputStream.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        return dest;
    }

    /**
     * 拷贝源对象的属性到目标对象
     * 
     * @param source 源对象
     * @param target 目标对象
     */
    public static <T, V> void copy(T source, V target) {
        if (source == null || target == null)
            return;

        BeanCopier beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);

        beanCopier.copy(source, target, null);
    }

    /**
     * 拷贝源对象的属性到目标类的实例，并返回目标类的实例
     * 
     * @param source 源对象
     * @param clazz  目标类
     * @return
     */
    public static <T, V> V convert(T source, Class<V> clazz) {
        if (source == null)
            return null;

        BeanCopier beanCopier = BeanCopier.create(source.getClass(), clazz, false);

        try {
            V targetObj = clazz.newInstance();

            beanCopier.copy(source, targetObj, null);

            return targetObj;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将源对象列表转换为目标类实例的列表
     * 
     * @param sourceList 源对象列表
     * @param clazz      目标类
     * @return
     */
    public static <T, V> List<V> convertList(List<T> sourceList, Class<V> clazz) {
        if (sourceList == null || sourceList.isEmpty())
            return null;

        List<V> targetList = new ArrayList<V>();

        BeanCopier beanCopier = null;

        for (T sourceObj : sourceList) {
            if (beanCopier == null) {
                beanCopier = BeanCopier.create(sourceObj.getClass(), clazz, false);
            }

            try {
                V targetObj = clazz.newInstance();

                beanCopier.copy(sourceObj, targetObj, null);

                targetList.add(targetObj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return targetList;
    }

	
}

class A{
	private String a;
	private String b;
	private String c;
	
	public String getA() {
		return a;
	}
	public void setA(String a) {
		this.a = a;
	}
	public String getB() {
		return b;
	}
	public void setB(String b) {
		this.b = b;
	}
	public String getC() {
		return c;
	}
	public void setC(String c) {
		this.c = c;
	}
}